﻿using Fluid;
using Fluid.Values;
using Newtonsoft.Json.Linq;
using ZYing.LiquidThemeEngine.Filters;
using ZYing.LiquidThemeEngine.Json;
using ZYing.LiquidThemeEngine.Objects;
using ZYing.LiquidThemeEngine.Paginating;

namespace ZYing.LiquidThemeEngine
{
    public class LiquidTemplateOptions : TemplateOptions
    {
        public LiquidTemplateOptions()
        {
            AddMemberAccessor();
            AddConverters();
            AddFilters();
            SetScope();
        }
        private void SetScope()
        {
            Scope.SetValue("__engine__", FluidValue.Create(new Engine(), this));
        }
        private void AddMemberAccessor()
        {
            MemberAccessStrategy.Register<Template>(LiquidThemeObjectAccessor.Instance);
            MemberAccessStrategy.Register<Paginate>(LiquidThemeObjectAccessor.Instance);
            MemberAccessStrategy.Register<Paginate.PaginatePart>(LiquidThemeObjectAccessor.Instance);
            MemberAccessStrategy.Register<Engine>(LiquidThemeObjectAccessor.Instance);
            MemberAccessStrategy.Register<Block>(LiquidThemeObjectAccessor.Instance);
            MemberAccessStrategy.Register<Section>(LiquidThemeObjectAccessor.Instance);
            MemberAccessStrategy.Register<JObject, object>((source, name) => source[name]);
        }

        private void AddConverters()
        {
            ValueConverters.Add(Convert);
        }

        private object Convert(object obj)
        {
            switch (obj)
            {
                case IPaginationSource source:
                    return new PaginationValue(source, this);
                case JObject jObject:
                    return new DictionaryValue(new JObjectFluidIndexable(jObject, this));
                case JValue jValue:
                    return jValue.Value;
            }

            return null;
        }

        private void AddFilters()
        {
            #region UrlFilters

            Filters.AddFilter("asset_url", UrlFilters.AssetUrlAsync);

            #endregion

            #region AdditionalFilters

            Filters.AddFilter("t", AdditionalFilters.TranslationAsync);
            Filters.AddFilter("default_pagination", AdditionalFilters.DefaultPaginationAsync);

            #endregion

            #region HtmlFilters

            Filters.AddFilter("img_tag", HtmlFilters.ImgTagAsync);

            #endregion
        }
    }
}